package com.demo.utils;

import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.tools.ant.taskdefs.Input;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class DownLoadZipUtil {
    /**
     * 将网络url资源文件的多个文件打包成压缩包并输出流下载
     * @param pathList
     * @param packageName
     * @param request
     * @param response
     * @return
     */
    public static boolean zipUrlToFile(List<Map<String, String>> pathList, String packageName, HttpServletRequest request, HttpServletResponse response) {
        try{
            ZipArchiveOutputStream zous =
                    getSerlvetOutputStream(packageName,response);

            for(Map<String, String> map : pathList) {
                String fileName = map.get("name");
                // fixme: 路径为空？
                InputStream inputStream =
                        getInputStreamFromUrl(map.get("path"));
                setByteArrayOutputStream(fileName,inputStream,zous);
            }
            zous.close();
            System.out.println("批量下载文件成功！");
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    private static ZipArchiveOutputStream getSerlvetOutputStream(String outputFileName,HttpServletResponse response) throws IOException {
        response.reset();
        response.setHeader("Content-Type", "application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(outputFileName, "UTF-8"));
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        ServletOutputStream out =
                response.getOutputStream();

        ZipArchiveOutputStream zous = new ZipArchiveOutputStream(out);
        zous.setUseZip64(Zip64Mode.AsNeeded);
        return zous;
    }

    /**
     * 通过网络地址获取InputStream
     * @param path 地址
     * @return
     */
    private static InputStream getInputStreamFromUrl(String path) throws UnsupportedEncodingException {
        URL url = null;
        InputStream is = null;
        //获取文件编码后的名字
        String fileNewName =
                path.substring(path.lastIndexOf("/")+1);
        System.out.println("shiadhianichsiao:"+fileNewName);
        String fileDownload = "http://localhost"
                + ":8081/tb_file/";
        try{
            url =
                    new URL(fileDownload+URLEncoder.encode(fileNewName,"utf-8"));
        }catch (MalformedURLException e) {
            e.printStackTrace();
        }
        try {
        HttpURLConnection conn =
                null;

            conn = (HttpURLConnection)url.openConnection();
            conn.setDoInput(true);
            conn.connect();
            is = conn.getInputStream();
        } catch (IOException e) {
           e.printStackTrace();
        }
       return is;
    }

    private static void setByteArrayOutputStream(String fileName,InputStream inputStream,ZipArchiveOutputStream zous) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while((len = inputStream.read(buffer)) != -1) {
            baos.write(buffer,0,len);
        }
        baos.flush();
        byte[] bytes = baos.toByteArray();
//        设置文件名
        ArchiveEntry entry =
                new ZipArchiveEntry(fileName);
        zous.putArchiveEntry(entry);
        zous.write(bytes);
        zous.closeArchiveEntry();
        baos.close();
    }
}
